package com.example.socket.model;

import com.alibaba.fastjson.JSONObject;
import com.example.common.HttpHandlerFilter;
import com.example.common.HttpHandlerWeb;
import com.example.http.HttpRequestServer;
import com.example.http.HttpRespServer;
import com.example.model.FormMulit;
import com.example.proxy.MethodProxy;
import com.example.socket.Servlet;
import com.example.socket.ServletRequest;
import com.example.socket.ServletResponse;
import com.example.util.ApplicationContent;
import com.example.util.Results;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Classname ServletModel
 * @Description TODO
 * @Date 2023/4/28 14:04
 * @Created by XiongXiong
 * @Author: X.I.O
 */
public class ServletModel extends Servlet {

    private String requestMethod;

    private MethodProxy methodProxy;

    private List<HttpHandlerWeb> httpHandlerWebList;

    private List<HttpHandlerFilter> httpHandlerFilterList;

    @Override
    public void doGet(ServletRequest request, ServletResponse response) {
        execute(request,response);
    }

    @Override
    public void doPost(ServletRequest request, ServletResponse response) {
        execute(request,response);
    }

    @Override
    public void service(ServletRequest request, ServletResponse response) {
        try {
            if(!request.getMethod().equalsIgnoreCase(requestMethod)){
                throw new Exception("请求方式不对");
            }
            if(request.getMethod().equalsIgnoreCase("POST")){
                doPost(request,response);
            }else if (request.getMethod().equalsIgnoreCase("GET")){
                doGet(request, response);
            }
        }catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 执行请求
     * @param request
     * @param response
     */
    public void execute(ServletRequest request, ServletResponse response)  {
        try {
            List<Object> objects=new ArrayList<>();
            if(!this.methodProxy.getMapArgModel().isEmpty()){
                addExecuteArgs(request,response,objects);
            }
            if(httpHandlerFilterList==null){
                httpHandlerFilterList= ApplicationContent.getObjList(HttpHandlerFilter.class);
            }
            if(httpHandlerFilterList.size() > 0){
                for (HttpHandlerFilter filter : httpHandlerFilterList){
                   boolean falg=filter.doFilter(request,response);
                   if(!falg){
                       response.wirte(Results.error("被拦截了").toJSONString());
                       return;
                   }
                }
            }
            if(httpHandlerWebList==null){
                httpHandlerWebList=ApplicationContent.getObjList(HttpHandlerWeb.class);
            }
            if(httpHandlerWebList.size()>0){
                for(HttpHandlerWeb httpHandlerWeb:httpHandlerWebList){
                    httpHandlerWeb.beforeHandler(request,response,objects);
                }
            }
            Object result=this.methodProxy.execute(objects.toArray());
            if(httpHandlerWebList.size()>0){
                for(HttpHandlerWeb httpHandlerWeb:httpHandlerWebList){
                    result=httpHandlerWeb.afterHandler(request,response,objects);
                }
            }
            response.wirte(JSONObject.toJSONString(result));
        }catch (Exception e){
            e.printStackTrace();
        }

    }

    /**
     * 添加执行参数
     */
    public void addExecuteArgs(ServletRequest request, ServletResponse response,List<Object> objects){
        List<MethodProxy.ArgModel> modelMaps=this.methodProxy.getArgModels();

        for(MethodProxy.ArgModel argModel : modelMaps){
            String argName =argModel.getName();
            Object val=null;
            if(argModel.getCls().getName().equals(ServletRequest.class.getName())){
                val=request;
            }else if(argModel.getCls().getName().equals(ServletResponse.class.getName())){
                val=response;
            }else if(argModel.getCls().getName().equals(MulitiFile.class.getName())){
                //处理上传的文件
                val=executeFormMulit(request,argModel);
            } else{
                if(request.getJson()!=null){
                    JSONObject json=request.getJson();
                    val=json.get(argName);
                }
                if(request.getFormData()!=null){
                    Map<String,Object> object=request.getFormData();
                    if(val==null){
                        val=object.get(argName);
                    }
                }
                if(request.getQueryMap()!=null){
                    if(val==null){
                        val=request.getQueryParamsFirst(argName);
                    }
                }
            }
            if(val==null){
                if(argModel.getDefaultValue()!=null && "".equals(argModel.getDefaultValue())){
                    val=argModel.getDefaultValue();
                }
                if(val==null && argModel.isRequired()){
                    //数据最后还是为空
                }
            }
            System.out.println("111222222   "+val);
            objects.add(val);
        }
    }


    /**
     * 处理文件上传
     * @return
     */
    private MulitiFile executeFormMulit(ServletRequest servletRequest,MethodProxy.ArgModel argModel){
        if(servletRequest.getFormData()==null){
            return null;
        }
        Map<String,Object> fromData=servletRequest.getFormData();

        Object value=fromData.get(argModel.getName());
        if(value==null){
            return null;
        }
        if(value instanceof MulitiFile){
            MulitiFile file=(MulitiFile)value;
            return file;
        }
        for (Map.Entry<String, Object> entry : fromData.entrySet()) {
            Object val=entry.getValue();
            if(val instanceof MulitiFile){
                MulitiFile file=(MulitiFile)value;
                return file;
            }
        }
        return null;
    }

    public ServletModel(MethodProxy methodProxy, String requestMethod) {
        this.methodProxy = methodProxy;
        this.requestMethod=requestMethod;
    }
}
